#include <SDL.h>
#include <stdio.h>
#include "init.h"
#include "main.h"
#include "keypress.h"
#include "texture.h"
#include <SDL_image.h>
#include "colorkey.h"

//#define KEYPRESS
//#define TEXTURE
//#define GEOMETRY_RENDER
//#define VIEWPORT
//#define COLORKEY
//#define CLIP_RENDER
//#define COLOR_MODULATION
#define ALPHA_BLENDING

int main( int argc, char* args[] ){

#ifdef ALPHA_BLENDING


#endif // ALPHA_BLENDING

#ifdef COLOR_MODULATION
    SDL_Window *cmWin = NULL;
    SDL_Renderer *cmRenderer = NULL;
    SDL_Texture *cmTexture = NULL;

    if(!initWindowAndRenderer(&cmWin, &cmRenderer)){
        printf("Failed to init!\n");
        return -1;
    }else{
        cmTexture = loadTextureEx("./img/fourcolor.png", &cmRenderer);

        bool quit = false;
        SDL_Event e;
        uint8_t r = 255;
        uint8_t g = 255;
        uint8_t b = 255;
        while(!quit){
            while(SDL_PollEvent(&e) != 0){
                if(e.type == SDL_QUIT){
                    quit = true;
                }else if(e.type == SDL_KEYDOWN){
                    switch(e.key.keysym.sym){
                        case SDLK_q:
                            r += 32;
                            break;
                        case SDLK_w:
                            g += 32;
                            break;
                        case SDLK_e:
                            b += 32;
                            break;
                        case SDLK_a:
                            r -= 32;
                            break;
                        case SDLK_s:
                            g -= 32;
                            break;
                        case SDLK_d:
                            b -= 32;
                            break;
                    }
                    printf("r=%d, g=%d, b=%d\n", r, g, b);

                }
                SDL_SetRenderDrawColor(cmRenderer, 0xff, 0xff, 0xff, 0xff);
                SDL_RenderClear(cmRenderer);
                SDL_SetTextureColorMod(cmTexture, r, g, b);
                SDL_RenderCopy(cmRenderer, cmTexture, NULL, NULL);
                SDL_RenderPresent(cmRenderer);
            }
        }
    }

#endif // COLOR_MODULATION

#ifdef CLIP_RENDER
    SDL_Window *crWin = NULL;
    SDL_Renderer *crRenderer = NULL;
    SDL_Surface *crSurface = NULL;
    SDL_Texture *crTexture = NULL;
    SDL_Rect rectClips[4];
    SDL_Rect rectRender;
    SDL_Surface *crIcon = NULL;

    if(SDL_Init(SDL_INIT_VIDEO) != 0){
        printf("Failed to init SDL: %s\n", SDL_GetError());
        return -1;
    }else{
        if(SDL_CreateWindowAndRenderer(WINDOW_WIDTH, WINDOW_HEIGHT, SDL_WINDOW_RESIZABLE, &crWin, &crRenderer) != 0){
            printf("Create window and renderer failed: %s\n", SDL_GetError());
            return -2;
        }else{
            crIcon = IMG_Load("./img/texture.png");
            SDL_SetWindowIcon(crWin, crIcon);
            SDL_FreeSurface(crIcon);
            crIcon = NULL;
            SDL_SetWindowTitle(crWin, "Test Clip Render");
            crSurface = IMG_Load("./img/round.png");

            if(!crSurface){
                printf("load image failed: %s\n", IMG_GetError());
                return -3;
            }else{
                crTexture = SDL_CreateTextureFromSurface(crRenderer, crSurface);
                SDL_FreeSurface(crSurface);
                crSurface = NULL;
                if(!crTexture){
                    printf("Create texture failed: %s\n", SDL_GetError());
                    return -4;
                }else{
                    //clear window
                    SDL_SetRenderDrawColor(crRenderer, 0xff, 0xff, 0xff, 0xff);
                    SDL_RenderClear(crRenderer);

                    bool quit = false;
                    SDL_Event e;
                    while(!quit){
                        while(SDL_PollEvent(&e)){
                            if(e.type == SDL_QUIT){
                                quit = true;
                            }
                        }
                        rectClips[0].x = 0;
                        rectClips[0].y = 0;
                        rectClips[0].w = 100;
                        rectClips[0].h = 100;
                        rectRender.x = 0;
                        rectRender.y = 0;
                        rectRender.w = rectClips[0].w;
                        rectRender.h = rectClips[0].h;
                        SDL_RenderCopy(crRenderer, crTexture, &rectClips[0], &rectRender);

                        rectClips[1].x = 100;
                        rectClips[1].y = 0;
                        rectClips[1].w = 100;
                        rectClips[1].h = 100;
                        rectRender.x = WINDOW_WIDTH - rectClips[1].w;
                        rectRender.y = 0;
                        rectRender.w = rectClips[1].w;
                        rectRender.h = rectClips[1].h;
                        SDL_RenderCopy(crRenderer, crTexture, &rectClips[1], &rectRender);

                        rectClips[2].x = 0;
                        rectClips[2].y = 100;
                        rectClips[2].w = 100;
                        rectClips[2].h = 100;
                        rectRender.x = 0;
                        rectRender.y = WINDOW_HEIGHT - rectClips[2].h;
                        rectRender.w = rectClips[2].w;
                        rectRender.h = rectClips[2].h;
                        SDL_RenderCopy(crRenderer, crTexture, &rectClips[2], &rectRender);

                        rectClips[3].x = 100;
                        rectClips[3].y = 100;
                        rectClips[3].w = 100;
                        rectClips[3].h = 100;
                        rectRender.x = WINDOW_WIDTH - rectClips[3].h;
                        rectRender.y = WINDOW_HEIGHT - rectClips[3].h;
                        rectRender.w = rectClips[3].w;
                        rectRender.h = rectClips[3].h;
                        SDL_RenderCopy(crRenderer, crTexture, &rectClips[3], &rectRender);

                        rectRender.x = WINDOW_WIDTH/2 - 200/2;
                        rectRender.y = WINDOW_HEIGHT/2 - 200/2;
                        rectRender.w = 200;
                        rectRender.h = 200;
                        SDL_RenderCopy(crRenderer, crTexture, NULL, &rectRender);

                        SDL_RenderPresent(crRenderer);
                    }

                }
            }
        }
    }

    SDL_DestroyWindow(crWin);
    SDL_DestroyRenderer(crRenderer);
    IMG_Quit();
    SDL_Quit();


#endif // CLIP_RENDER

#ifdef COLORKEY
    SDL_Window *ckWin = NULL;
    SDL_Renderer *ckRenderer = NULL;
    Texture_t personTexture, backgroundTexture;

    if(SDL_Init(SDL_INIT_VIDEO) != 0){
        printf("Unable to init SDL: %s\n", SDL_GetError());
        return -1;
    }else{
        if(SDL_CreateWindowAndRenderer(WINDOW_WIDTH, WINDOW_HEIGHT, SDL_WINDOW_RESIZABLE, &ckWin, &ckRenderer) != 0){
            printf("Create window and renderer failed: %s\n", SDL_GetError());
            return -2;
        }else{
            initTexture(&personTexture, ckRenderer, "./img/person.png");
            initTexture(&backgroundTexture, ckRenderer, "./img/background.png");

            loadFromFile(&personTexture);
            loadFromFile(&backgroundTexture);
            renderTexture(&backgroundTexture, 0, 0);
            renderTexture(&personTexture, 200, 120);
            int x = 200, y = 120;
            bool quit = false;
            SDL_Event e;
            while(!quit){
                while(SDL_PollEvent(&e) != 0){
                    if(e.type == SDL_QUIT){
                        quit = true;
                    }else{
                        if(e.type == SDL_KEYDOWN){
                            switch(e.key.keysym.sym){
                                case SDLK_LEFT:
                                    if(x > 5)
                                        x -= 5;
                                    break;
                                case SDLK_RIGHT:
                                    if(x < WINDOW_WIDTH - personTexture.imgWidth)
                                        x += 5;
                                    break;
                                case SDLK_UP:
                                    if(y > 5)
                                        y -= 5;
                                    break;
                                case SDLK_DOWN:
                                    if(y < WINDOW_HEIGHT - personTexture.imgHeight)
                                        y += 5;
                                    break;
                            }
                            renderTexture(&backgroundTexture, 0, 0);
                            renderTexture(&personTexture, x, y);
                            SDL_RenderPresent(ckRenderer);
                        }

                    }
                }
                SDL_RenderPresent(ckRenderer);
            }
        }
    }

    freeTexture(&personTexture);
    freeTexture(&backgroundTexture);
    SDL_DestroyWindow(ckWin);
    SDL_DestroyRenderer(ckRenderer);
    IMG_Quit();
    SDL_Quit();

#endif // COLORKEY

#ifdef VIEWPORT
    SDL_Window *vpWin = NULL;
    SDL_Texture *vpTexture = NULL;
    SDL_Renderer *vpRenderer = NULL;
    SDL_Surface *vpSurface = NULL;

    if(SDL_Init(SDL_INIT_VIDEO) != 0){
        printf("Unable to init SDL: %s\n", SDL_GetError());
        return -1;
    }else{
        if(SDL_CreateWindowAndRenderer(WINDOW_WIDTH, WINDOW_HEIGHT, SDL_WINDOW_RESIZABLE, &vpWin, &vpRenderer) != 0){
            printf("Unable to create window and renderer: %s\n", SDL_GetError());
            return -1;
        }else{
            vpSurface = IMG_Load("./img/texture.png");
            vpTexture = SDL_CreateTextureFromSurface(vpRenderer, vpSurface);
            SDL_FreeSurface(vpSurface);

            SDL_SetRenderDrawColor(vpRenderer, 255, 165, 0, 0xff);
            SDL_RenderClear(vpRenderer);

            SDL_Rect topLeftRect = {0, 0, WINDOW_WIDTH/2, WINDOW_HEIGHT/2};
            SDL_RenderSetViewport(vpRenderer, &topLeftRect);
            SDL_RenderCopy(vpRenderer, vpTexture, NULL, NULL);

            SDL_Rect topRigntRect = {WINDOW_WIDTH/2, 0, WINDOW_WIDTH/2, WINDOW_HEIGHT/2};
            SDL_RenderSetViewport(vpRenderer, &topRigntRect);
            SDL_RenderCopy(vpRenderer, vpTexture, NULL, NULL);

            SDL_Rect bottomRect = {0, WINDOW_HEIGHT/2, WINDOW_WIDTH, WINDOW_HEIGHT/2};
            SDL_RenderSetViewport(vpRenderer, &bottomRect);
            SDL_RenderCopy(vpRenderer, vpTexture, NULL, NULL);

            SDL_RenderPresent(vpRenderer);
            SDL_Delay(5000);
        }
    }

    SDL_Quit();

#endif // VIEWPORT

#ifdef GEOMETRY_RENDER
    SDL_Window *geoWin = NULL;
    SDL_Renderer *geoRenderer = NULL;

    if(SDL_Init(SDL_INIT_VIDEO) != 0){
        printf("Unable to init SDL: %s\n", SDL_GetError());
        return -1;
    }else{
        if(SDL_CreateWindowAndRenderer(WINDOW_WIDTH, WINDOW_HEIGHT, SDL_WINDOW_RESIZABLE, &geoWin, &geoRenderer)){
            printf("Unable to create window and renderer: %s\n", SDL_GetError());
            return -1;
        }else{
            //clear window with drawing color
            SDL_SetRenderDrawColor(geoRenderer, 0xff, 0xff, 0xff, 0xff);
            SDL_RenderClear(geoRenderer);
            //draw rectangle
            SDL_Rect fillRect = {WINDOW_WIDTH/4, WINDOW_HEIGHT/4, WINDOW_WIDTH/2, WINDOW_HEIGHT/2};
            SDL_SetRenderDrawColor(geoRenderer, 0, 0, 0xff, 0xff);
            SDL_RenderFillRect(geoRenderer, &fillRect);
            //draw outline rectangle
            SDL_Rect outlineRect = {WINDOW_WIDTH/8, WINDOW_HEIGHT/8, WINDOW_WIDTH*3/4, WINDOW_HEIGHT*3/4};
            SDL_SetRenderDrawColor(geoRenderer, 0xff, 0, 0, 0xff);
            SDL_RenderDrawRect(geoRenderer, &outlineRect);
            //draw line
            SDL_SetRenderDrawColor(geoRenderer, 0, 0xff, 0, 0xff);
            SDL_RenderDrawLine(geoRenderer, 0, WINDOW_HEIGHT/2, WINDOW_WIDTH, WINDOW_HEIGHT/2);
            //draw point
            SDL_SetRenderDrawColor(geoRenderer, 0xff, 0, 0xff, 0xff);
            for(int i = 0; i < WINDOW_HEIGHT; i += 5){
                SDL_RenderDrawPoint(geoRenderer, WINDOW_WIDTH/2, i);
            }

            SDL_RenderPresent(geoRenderer);
            SDL_Delay(3000);
        }
    }

    SDL_DestroyWindow(geoWin);
    SDL_DestroyRenderer(geoRenderer);
    SDL_Quit();

#endif // GEOMETRY_RENDER


#ifdef KEYPRESS

    if(false == init()){
        printf("Failed to init!\n");
        return -1;
    }else{
        if(false == loadMedia()){
            printf("Failed to load media!\n");
            return -1;
        }else{
            bool quit = false;
            SDL_Event e;
            gCurSurface = gKeyPressSurfaces[KEY_PRESS_SURFACE_DEFAULT];
            while(!quit){
                while(SDL_PollEvent(&e) != 0){
                    if(SDL_QUIT == e.type){
                        quit = true;
                    }else if(SDL_KEYDOWN == e.type){
                        //printf("key code = %d\n", e.key.keysym.sym);
                        switch(e.key.keysym.sym){
                            case SDLK_UP:
                                printf("press up\n");
                                gCurSurface = gKeyPressSurfaces[KEY_PRESS_SURFACE_UP];
                                break;

                            case SDLK_DOWN:
                                printf("press down\n");
                                gCurSurface = gKeyPressSurfaces[KEY_PRESS_SURFACE_DOWN];
                                break;

                            case SDLK_LEFT:
                                printf("press left\n");
                                gCurSurface = gKeyPressSurfaces[KEY_PRESS_SURFACE_LEFT];
                                break;

                            case SDLK_RIGHT:
                                printf("press right\n");
                                gCurSurface = gKeyPressSurfaces[KEY_PRESS_SURFACE_RIGHT];
                                break;

                            case SDLK_SPACE:
                                printf("press space\n");
                                gCurSurface = gKeyPressSurfaces[KEY_PRESS_SURFACE_SPACE];
                                break;

                            case SDLK_RETURN:
                                printf("press enter\n");
                                gCurSurface = gKeyPressSurfaces[KEY_PRESS_SURFACE_ENTER];
                                break;
                        }
                    }
                }

                SDL_BlitScaled(gCurSurface, NULL, gWinSurface, &gWinRect);
                SDL_UpdateWindowSurface(gWin);
            }
        }
    }

    freeMedia();

#endif // KEYPRESS

#ifdef TEXTURE

    // image=>surface=>texture=>renderer
    if(false == init2()){
        printf("Failed to init2!\n");
        return -1;
    }else{
        gTexture = loadTexture("./img/texture.png");
        if(!gTexture){
            printf("Load texture failed: %s\n", SDL_GetError());
            return -1;
        }else{
            SDL_RenderClear(gRender);
            SDL_RenderCopy(gRender, gTexture, NULL, NULL);
            SDL_RenderPresent(gRender);
            SDL_Delay(3000);
        }
    }

#endif // TEXTURE

    return 0;
}
